#pragma once



#include <iostream>
#include <string>
#include <cstdio>
#include <set>

const int line_size = 1024;

class Command
{
private:
    using command_t = std::string;
public:
    Command(){
        _white_list.insert("ls");
        _white_list.insert("pwd");
        _white_list.insert("ls -l");
        _white_list.insert("ll");
        _white_list.insert("who");
        _white_list.insert("whoami");
    }

    bool SafeCheck(const std::string &cmdstr){
        auto iter = _white_list.find(cmdstr);
        return iter != _white_list.end();
    }

    // 给你一个命令字符串 "ls -l" 让你执行，执行完，把结果返回
    std::string Execute(std::string cmd){
        // 安全检查
        if(!SafeCheck(cmd)) return std::string(cmd + "不支持");

        // 1. pipe
        // 2. fork + dup2(pipe[1], 1) +exec* 接口，把执行结果给父进程(pipe通信)pipe[0]读端
        // 3. return
        // popen C语言库的接口做了上面三个工作
        FILE *fp = ::popen(cmd.c_str(), "r");
        if(fp == nullptr){
            return std::string("Failed");
        }

        char buffer[line_size];
        std::string result;
        while(true){
            char *ret = ::fgets(buffer,sizeof(buffer), fp);
            if(ret == nullptr){
                break;
            }
            result += ret;
        }

        pclose(fp);
        return result.empty() ? std::string("Done") : result; //防止没有回显时 不知道已经执行完
    }
private:
    std::set<command_t> _white_list;
};


